//! MathML支持模块
//!
//! 提供解析和处理MathML元素的功能

use crate::{DomNode, NodeType, Attribute, HtmlParserError};
use std::borrow::Cow;
use std::collections::HashSet;
use once_cell::sync::Lazy;

/// MathML命名空间URI
pub const MATHML_NAMESPACE: &str = "http://www.w3.org/1998/Math/MathML";

/// MathML元素名称集合
static MATHML_ELEMENTS: Lazy<HashSet<&'static str>> = Lazy::new(|| {
    let mut elements = HashSet::new();
    // 添加MathML核心元素
    elements.insert("math");
    elements.insert("mi");
    elements.insert("mn");
    elements.insert("mo");
    elements.insert("mtext");
    elements.insert("mrow");
    elements.insert("mfrac");
    elements.insert("msqrt");
    elements.insert("mroot");
    elements.insert("msub");
    elements.insert("msup");
    elements.insert("msubsup");
    elements.insert("munder");
    elements.insert("mover");
    elements.insert("munderover");
    elements.insert("mtable");
    elements.insert("mtr");
    elements.insert("mtd");
    elements.insert("mspace");
    elements.insert("mstyle");
    elements.insert("merror");
    elements.insert("mpadded");
    elements.insert("mphantom");
    elements.insert("menclose");
    elements.insert("mglyph");
    elements.insert("ms");
    elements
});

/// MathML属性名称集合
static MATHML_ATTRIBUTES: Lazy<HashSet<&'static str>> = Lazy::new(|| {
    let mut attributes = HashSet::new();
    // 添加基本MathML属性
    attributes.insert("display");
    attributes.insert("mathvariant");
    attributes.insert("mathsize");
    attributes.insert("mathcolor");
    attributes.insert("mathbackground");
    attributes.insert("scriptlevel");
    attributes.insert("linethickness");
    attributes.insert("stretchy");
    attributes.insert("fence");
    attributes.insert("separator");
    attributes.insert("accent");
    attributes.insert("lspace");
    attributes.insert("rspace");
    attributes.insert("numalign");
    attributes.insert("denomalign");
    attributes.insert("bevelled");
    attributes.insert("notation");
    attributes.insert("subscriptshift");
    attributes.insert("superscriptshift");
    attributes.insert("movablelimits");
    attributes.insert("form");
    attributes
});

/// 检查是否为MathML元素
pub fn is_mathml_element(tag_name: &str) -> bool {
    MATHML_ELEMENTS.contains(&tag_name.to_lowercase().as_str())
}

/// 检查是否为MathML属性
pub fn is_mathml_attribute(attr_name: &str) -> bool {
    MATHML_ATTRIBUTES.contains(&attr_name.to_lowercase().as_str())
}

/// 创建MathML命名空间的元素
pub fn create_mathml_element(tag_name: &str) -> DomNode {
    DomNode {
        node_type: NodeType::Element(Cow::Owned(tag_name.to_string())),
        namespace: Some(MATHML_NAMESPACE.to_string()),
        attributes: Vec::new(),
        children: Vec::new(),
        parent: None,
    }
}

/// 为MathML元素添加默认属性
pub fn add_default_mathml_attributes(node: &mut DomNode) {
    if let NodeType::Element(tag_name) = &node.node_type {
        if tag_name.as_ref() == "math" && !node.has_attribute("xmlns") {
            node.add_attribute("xmlns", MATHML_NAMESPACE);
        }
    }
}

/// 验证MathML元素的合法性
pub fn validate_mathml_element(node: &DomNode) -> Result<(), HtmlParserError> {
    if let NodeType::Element(tag_name) = &node.node_type {
        if !is_mathml_element(tag_name.as_ref()) {
            return Err(HtmlParserError::InvalidNode(
                format!("无效的MathML元素: {}", tag_name)
            ));
        }
        
        // 检查特定元素的要求
        match tag_name.as_ref() {
            "mfrac" => {
                // mfrac应该有两个子元素(分子和分母)
                if node.children.len() != 2 {
                    return Err(HtmlParserError::InvalidNode(
                        "mfrac元素必须恰好有两个子元素".to_string()
                    ));
                }
            },
            "msqrt" => {
                // msqrt至少有一个子元素
                if node.children.is_empty() {
                    return Err(HtmlParserError::InvalidNode(
                        "msqrt元素必须至少有一个子元素".to_string()
                    ));
                }
            },
            "mroot" => {
                // mroot应该有两个子元素(基数和指数)
                if node.children.len() != 2 {
                    return Err(HtmlParserError::InvalidNode(
                        "mroot元素必须恰好有两个子元素".to_string()
                    ));
                }
            },
            _ => {}
        }
    }
    
    Ok(())
}
